home *** CD-ROM | disk | FTP | other *** search
/ Merciful 5 / Merciful - Disc 5.iso / software / p / pcqpascalv1.2d.lha / Examples2 / KeySim / KeySim.p < prev   
Text File  |  1997-05-06  |  10KB  |  400 lines

  1. Program HotKey;
  2.  
  3. { /// ------------------------------ "includes" ------------------------------ }
  4.  
  5. {$I "Include:Intuition/Intuition.i"}
  6. {$I "Include:Exec/Ports.i"}
  7. {$I "Include:Exec/Libraries.i"}
  8. {$I "Include:Exec/Tasks.i"}
  9. {$I "Include:Exec/Memory.i"}
  10. {$I "Include:Exec/IO.i"}
  11. {$I "Include:Exec/Devices.i"}
  12. {$I "Include:Devices/Input.i"}
  13. {$I "Include:Devices/InputEvent.i"}
  14. {$I "Include:Devices/KeyMap.i"}
  15. {$I "Include:Devices/Console.i"}
  16. {$I "Include:Devices/ConUnit.i"}
  17. {$I "Include:Libraries/Commodities.i"}
  18. {$I "Include:Libraries/Asl.i"}
  19. {$I "Include:DOS/DOS.i"}
  20. {$I "Include:Utils/IOUtils.i"}
  21. {$I "Include:Utils/StringLib.i"}
  22. {$I "Include:Utils/Parameters.i"}
  23. {$I "Include:Utility/TagItem.i"}
  24.  
  25. { /// ------------------------------------------------------------------------ }
  26.  
  27. { /// ----------------------------- "variables" ------------------------------ }
  28.  
  29. const EVT_HOTKEY : Integer = 1;
  30.  
  31.     nb : newbroker = (
  32.     NB_VERSION,
  33.     "KeySim",           { string to identify this broker }
  34.     "KeySim v0.2 - 1995 Andreas Tetzl",
  35.     "A keyboard simulator",
  36.     NBU_UNIQUE OR NBU_NOTIFY,
  37.     COF_SHOW_HIDE, 0, NIL, 0
  38. );
  39.  
  40.     HotKey = "ctrl alt v";
  41.  
  42. Const
  43.  StdInName : String = NIL;
  44.  StdOutName : String = NIL;
  45.  Version = "$VER: KeySim 0.2 (5.7.95)";
  46.  
  47.  KEYDELAY = 0;  { Wartezeit in Ticks nach beliebiger Taste }
  48.  CRDELAY  = 50; { Wartezeit in Ticks nach CR (ENTER) }
  49.  
  50. Type
  51.  Key_Struct = Record
  52.   Code      : Byte;
  53.   Qualifier : WORD;
  54.  end;
  55.  
  56. VAR
  57.     ASCII : Array[0..255] of Key_Struct;
  58.     filename, dir : String;
  59.     c : Byte;
  60.  
  61.     broker_mp : MsgPortPtr;
  62.     broker,filter,sender,translate : CxObjPtr;
  63.     cxsigflag : Integer;
  64.     Msg : CxMsgPtr;
  65.  
  66. { /// ------------------------------------------------------------------------ }
  67.  
  68. { /// --------------------------- "PROCEDURE Req" ---------------------------- }
  69.  
  70. PROCEDURE Req(Txt : String);
  71. const
  72.     es : EasyStruct = (0,0,NIL,NIL,NIL);
  73.  
  74. VAR i : Integer;
  75.  
  76. begin
  77.  es.es_StructSize:=SizeOf(EasyStruct);
  78.  es.es_Flags:=0;
  79.  es.es_Title:="Information";
  80.  es.es_TextFormat:=Txt;
  81.  es.es_GadgetFormat:="OK";
  82.  
  83.  i:=EasyRequestArgs(NIL,adr(es),0,NIL);
  84. END;
  85.  
  86. { /// ------------------------------------------------------------------------ }
  87.  
  88. { /// ------------------------ "PROCEDURE CleanExit" ------------------------- }
  89.  
  90. PROCEDURE CleanExit(Why : String; RC : Integer);
  91. BEGIN
  92.  If broker<>NIL then DeleteCxObjAll(broker);
  93.  
  94.  If broker_mp<>NIL then
  95.   BEGIN
  96.    Msg:=CxMsgPtr(GetMsg(broker_mp));
  97.    While Msg<>NIL do
  98.    BEGIN
  99.     ReplyMsg(MessagePtr(msg));
  100.     Msg:=CxMsgPtr(GetMsg(broker_mp));
  101.    end;
  102.  
  103.    DeleteMsgPort(broker_mp);
  104.   END;
  105.  
  106.  If CxBase<>NIL then CloseLibrary(CxBase);
  107.  If Why<>NIL then Req(Why);
  108.  Exit(RC);
  109. END;
  110.  
  111. { /// ------------------------------------------------------------------------ }
  112.  
  113. { /// ---------------------- "PROCEDURE CheckFile" --------------------------- }
  114.  
  115. FUNCTION CheckFile : Boolean;
  116. VAR OldDir, NewDir, f : FileLock;
  117. BEGIN
  118.  OldDir:=NIL;
  119.  NewDir:=Lock(dir,SHARED_LOCK);
  120.  If NewDir<>NIL then OldDir:=CurrentDir(NewDir);
  121.  
  122.  f:=Lock(filename,SHARED_LOCK);
  123.  If f=NIL then
  124.   BEGIN
  125.    If OldDir<>NIL then NewDir:=CurrentDir(OldDir);
  126.    CheckFile:=FALSE;
  127.   END;
  128.  
  129.  UnLock(f);
  130.  If OldDir<>NIL then NewDir:=CurrentDir(OldDir);
  131.  CheckFile:=TRUE;
  132. END;
  133.  
  134. { /// ------------------------------------------------------------------------ }
  135.  
  136. { /// ----------------------- "PROCEDURE FileRequest" ------------------------ }
  137.  
  138. FUNCTION FileRequest : Boolean;
  139. VAR fr : FileRequesterPtr;
  140.     OK : Boolean;
  141.     TagList : Array[0..1] of TagItem;
  142. BEGIN
  143.  AslBase:=OpenLibrary("asl.library",37);
  144.  If AslBase=NIL then FileRequest:=FALSE;
  145.  
  146.  TagList[0].ti_Tag:=ASL_Hail;
  147.  TagList[0].ti_Data:=Integer("KeySim: HotKey = <ctrl alt v>");
  148.  TagList[1].ti_Tag:=TAG_DONE;
  149.  
  150.  fr:=AllocAslRequest(ASL_FileRequest,adr(TagList));
  151.  If fr=NIL then
  152.   BEGIN
  153.    CloseLibrary(AslBase);
  154.    FileRequest:=FALSE;
  155.   END;
  156.  
  157.  OK:=AslRequest(fr,NIL);
  158.  If OK=FALSE then
  159.   BEGIN
  160.    FreeAslRequest(fr);
  161.    CloseLibrary(AslBase);
  162.    FileRequest:=FALSE;
  163.   END;
  164.  
  165.  StrCpy(filename,fr^.rf_File);
  166.  StrCpy(dir,fr^.rf_Dir);
  167.  
  168.  FreeAslRequest(fr);
  169.  CloseLibrary(AslBase);
  170.  
  171.  FileRequest:=TRUE;
  172. END;
  173.  
  174. { /// ------------------------------------------------------------------------ }
  175.  
  176. { /// ------------------------- "PROCEDURE WriteKey" ------------------------- }
  177.  
  178. PROCEDURE WriteKey(asc : Byte);
  179. VAR event       : InputEvent;
  180.     err : Integer;
  181.     port        : MsgPortPtr;
  182.     ioreq       : IOStdReqPtr;
  183. BEGIN
  184.  port := CreatePort (NIL, 0);
  185.  ioreq := CreateStdIO (port);
  186.  err:=OpenDevice ("input.device", 0, ioreq, 0);
  187.  
  188.  { key down }
  189.  
  190.  event.ie_Class:=IECLASS_RAWKEY;
  191.  event.ie_Code:=ASCII[asc].Code;
  192.  event.ie_Qualifier:=ASCII[asc].Qualifier;
  193.  
  194.  ioreq^.io_Data := adr(event);
  195.  ioreq^.io_Command := IND_WRITEEVENT;
  196.  ioreq^.io_Length:=sizeof(inputevent);
  197.  err := DoIO (ioreq);
  198.  
  199.  { key up }
  200.  
  201.  event.ie_Class:=IECLASS_RAWKEY;
  202.  event.ie_Code:=ASCII[asc].Code OR IECODE_UP_PREFIX;
  203.  event.ie_Qualifier:=ASCII[asc].Qualifier;
  204.  
  205.  ioreq^.io_Data := adr(event);
  206.  ioreq^.io_Command := IND_WRITEEVENT;
  207.  ioreq^.io_Length:=sizeof(inputevent);
  208.  err := DoIO (ioreq);
  209.  
  210.  If ioreq<>NIL then CloseDevice (ioreq);
  211.  If ioreq<>NIL then DeleteStdIO (ioreq);
  212.  If port<>NIL then DeletePort (port);
  213. END;
  214.  
  215. { /// ------------------------------------------------------------------------ }
  216.  
  217. { /// -------------------------- "PROCEDURE KeySim" -------------------------- }
  218.  
  219. PROCEDURE KeySim;
  220. VAR FH : FileHandle;
  221.     err : Integer;
  222.     OldDir, NewDir : FileLock;
  223. BEGIN
  224.  OldDir:=NIL;
  225.  NewDir:=Lock(dir,SHARED_LOCK);
  226.  If NewDir<>NIL then OldDir:=CurrentDir(NewDir);
  227.  
  228.  FH:=DOSOpen(filename,MODE_OLDFILE);
  229.  If OldDir<>NIL then NewDir:=CurrentDir(OldDir);
  230.  If FH=NIL then
  231.   BEGIN
  232.    DisplayBeep(NIL);
  233.    Return;
  234.   END;
  235.  
  236.  err:=Seek(FH,0,OFFSET_BEGINNING);
  237.  err:=DOSRead(FH,adr(c),1);
  238.  While err<>0 do
  239.   BEGIN
  240.    Delay(KEYDELAY);
  241.    WriteKey(c);
  242.    If c=10 then Delay(CRDELAY);
  243.    err:=DOSRead(FH,adr(c),1);
  244.   END;
  245.  
  246.  DOSClose(FH);
  247. END;
  248.  
  249. { /// ------------------------------------------------------------------------ }
  250.  
  251. { /// ----------------------- "PROCEDURE CreateASCII" ------------------------ }
  252.  
  253. PROCEDURE CreateASCII;
  254. Var port        : MsgPortPtr;
  255.     conreq      : IOStdReqPtr;
  256.     keys : KeyMapPtr;
  257.     event       : InputEvent;
  258.     buffer : String;
  259.     i, j, err : Integer;
  260.  
  261. BEGIN
  262.  port:=CreatePort(NIL,0);
  263.  conreq:=CreateStdIO(port);
  264.  err:=OpenDevice("console.device",CONU_LIBRARY,conreq,0);
  265.  if err<>0 then CleanExit("Console",10);
  266.  
  267.  ConsoleBase:=conreq^.io_Device;
  268.  
  269.  New(keys);
  270.  conreq^.io_Data:=keys;
  271.  conreq^.io_Length:=SizeOf(KeyMap);
  272.  conreq^.io_Command:=CD_ASKKEYMAP;
  273.  err:=DoIO(conreq);
  274.  If err<>0 then CleanExit("DoIO",err);
  275.  
  276.  Buffer:=AllocString(20);
  277.  For i:=0 to 64 do
  278.   BEGIN
  279.    For j:=1 to 3 do
  280.     BEGIN
  281.      StrCpy(Buffer,"");
  282.      event.ie_NextEvent:=NIL;
  283.      event.ie_Class:=IECLASS_RAWKEY;
  284.      event.ie_Code:=i;
  285.      Case j of
  286.       1 : event.ie_Qualifier:=0;
  287.       2 : event.ie_Qualifier:=IEQUALIFIER_LSHIFT;
  288.       3 : event.ie_Qualifier:=IEQUALIFIER_LALT;
  289.      end;
  290.  
  291.      err:=RawKeyConvert(adr(event),Buffer,10,keys);
  292.      If (err<>0) and (Ord(Buffer[0])>=0) and (Ord(Buffer[0])<=255) then
  293.       BEGIN
  294.        ASCII[Ord(Buffer[0])].Code:=event.ie_Code;
  295.        ASCII[Ord(Buffer[0])].Qualifier:=event.ie_Qualifier;
  296.       END;
  297.     END;
  298.   END;
  299.  
  300.  ASCII[10].Code:=$44;
  301.  ASCII[10].Qualifier:=0;
  302.  
  303.  CloseDevice (conreq);
  304.  DeleteStdIO (conreq);
  305.  DeletePort (port);
  306. END;
  307.  
  308. { /// ------------------------------------------------------------------------ }
  309.  
  310. { /// ------------------------ "PROCEDURE ProcessMsg" ------------------------ }
  311.  
  312. PROCEDURE ProcessMsg;
  313. VAR sigrcvd, msgid, msgtype : Integer;
  314.     returnvalue : Boolean;
  315.  
  316. begin
  317.  returnvalue:=TRUE;
  318.  while returnvalue do
  319.   Begin
  320.    sigrcvd := Wait(cxsigflag OR SIGBREAKF_CTRL_C);
  321.  
  322.    if (sigrcvd AND SIGBREAKF_CTRL_C)=SIGBREAKF_CTRL_C then
  323.     Begin
  324.      returnvalue := FALSE;
  325.     end;
  326.  
  327.    Msg:=CXMsgPtr(GetMsg(broker_mp));
  328.    While Msg<>NIL do
  329.     Begin
  330.      msgid := CxMsgID(msg);
  331.      msgtype := CxMsgType(msg);
  332.      ReplyMsg(MessagePtr(msg));
  333.  
  334.      Case MsgType of
  335.       CXM_IEVENT : Begin
  336.                     If msgid=EVT_HOTKEY then KeySim;
  337.                    end;
  338.       CXM_COMMAND : Begin
  339.                      Case msgid of
  340.                       CXCMD_DISABLE : If ActivateCxObj(broker, 0)=0 then;
  341.                       CXCMD_ENABLE  : If ActivateCxObj(broker, 1)=0 then;
  342.                       CXCMD_KILL    : returnvalue := FALSE;
  343.                       CXCMD_UNIQUE  : returnvalue := FALSE;
  344.                       CXCMD_APPEAR  : If FileRequest=FALSE then
  345.                                        If CheckFile=FALSE then Req("can't open file");
  346.                      end;
  347.                     end;
  348.      end;
  349.      Msg:=CXMsgPtr(GetMsg(broker_mp));
  350.     end;
  351.   end;
  352. end;
  353.  
  354. { /// ------------------------------------------------------------------------ }
  355.  
  356. { /// -------------------------------- "main" -------------------------------- }
  357.  
  358. Begin
  359.  filename:=AllocString(300);
  360.  dir:=AllocString(300);
  361.  GetParam(1, filename);
  362.  
  363.  If StrEq(filename,"") then
  364.   If FileRequest=FALSE then CleanExit(NIL,10);
  365.  If StrEq(filename,"") then CleanExit("no file",10);
  366.  If CheckFile=FALSE then CleanExit("can't open file",10);
  367.  
  368.  CreateASCII;
  369.  
  370.  CxBase := OpenLibrary("commodities.library", 37);
  371.  If cxBase=NIL then CleanExit("commodities",10);
  372.  
  373.  broker_mp := CreateMsgPort;
  374.  
  375.  cxsigflag := 1 shl broker_mp^.mp_SigBit;
  376.  nb.nb_Port := broker_mp;
  377.  nb.nb_Pri:=0;
  378.  
  379.  broker := CxBroker(adr(nb), NIL);
  380.  
  381.  filter := CreateCxObj(CX_FILTER, Integer(HotKey) ,0);
  382.  AttachCxObj(broker, filter);
  383.  
  384.  sender := CreateCxObj(CX_SEND, Integer(broker_mp), EVT_HOTKEY);
  385.  AttachCxObj(filter, sender);
  386.  
  387.  translate := CreateCxObj(CX_TRANSLATE,0,0);
  388.  AttachCxObj(filter, translate);
  389.  
  390.  If CxObjError(filter)=0 then
  391.   Begin
  392.    If ActivateCxObj(broker, 1)=0 then;
  393.    ProcessMsg;
  394.   end;
  395.  
  396.  CleanExit(NIL,0);
  397. end.
  398.  
  399. { /// ------------------------------------------------------------------------ }
  400.